package ru.hh.team02.chat.client;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.Queue;

/*
При запуске задавать адрес/имя сервера(порт сервера захардкоден - 4444), если нужно - порт для внутреннего общения.
*/

public class ClientReader implements Runnable {
	private final static int SERVER_PORT = 4444;
	private final static int CLIENT_PORT = 5555;
	
	private ObjectInputStream netInputStream;
	private ObjectOutputStream netOutputStream;
	private int clientPort;
	private String serverName;
	private Socket socket;
//	private Queue<String> userInputQueue = new LinkedList<String>();
//	private ObjectOutputStream localOutputStream;
	private Object SyncronizingObject = new Object();

	public static void main(String[] args) {
		int clientPort;
		if (args.length == 0) {
			System.out.println("Parameter server name s needed");
			System.exit(0);
		}
		if (args.length == 1) {
			clientPort = CLIENT_PORT;
		} else {
			clientPort = Integer.parseInt(args[1]);
		}
		new ClientReader(args[0], clientPort).run();
	}
	
	public ClientReader(String serverName, int clientPort) {
		this.serverName = serverName;
		this.clientPort = clientPort;
	}
	
	private void connect() throws Exception {
		if (!serverName.equals("stub")) {
			socket = new Socket(serverName, SERVER_PORT);
			netInputStream = new ObjectInputStream(socket.getInputStream());
			netOutputStream = new ObjectOutputStream(socket.getOutputStream());
		} else {
			netInputStream = new ObjectInputStream(new FileInputStream("C:\\stub.in"));
			netOutputStream = new ObjectOutputStream(new FileOutputStream("C:\\stub.out"));	
		}
	}
	
	private void startWriterListener() throws Exception {
		new Thread(new Runnable() {
			@Override
			public void run() {
				Socket localSocket = null;
				try {
					ServerSocket serverSocket = new ServerSocket(clientPort);
					System.out.println("For writing lunch ClientWriter");
					System.out.println("Input login");
					localSocket = serverSocket.accept();
					serverSocket.close();
					ObjectInputStream localInputStream = new ObjectInputStream(localSocket.getInputStream());
					while(true) {
						String login = (String)localInputStream.readObject();
						netOutputStream.writeObject(login);
						String answer = (String)netInputStream.readObject();
						System.out.println(answer);
						if (answer.equals("Ok")) {
							break;
						}
						System.out.println("Input login");
					}
					while(true) {
						System.out.println("Input room name");
						String roomName = (String)localInputStream.readObject();
						netOutputStream.writeObject(roomName);
						String answer = (String)netInputStream.readObject();
						System.out.println(answer);
						if (answer.equals("Ok")) {
							break;
						}
					}
					synchronized(SyncronizingObject) {
						SyncronizingObject.notify();
					}
					while(true) {
						String message = (String)localInputStream.readObject();
						netOutputStream.writeObject(message);
						System.out.println(message);
						if (message.equals("exit")) {
							socket.close();
							System.exit(0);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					try {
						if (localSocket != null) {
							localSocket.close();
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
	}

	@Override
	public void run() {
		try {
			connect();
			String serverTextName = (String)netInputStream.readObject();
			System.out.println("Welcome to " + serverTextName);
			startWriterListener();
			
			synchronized(SyncronizingObject) {
				SyncronizingObject.wait();
			}
			while(true) {
				String message = (String)netInputStream.readObject();
				System.out.println(message);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
